/**
 * 
 * @brief  bsp_mipi.h
 * @param  None
 * 
 * @author xhq
 * @date   2024/11/07
 * 
 */
#ifndef __SRC_BSP_MIPI_H__
#define __SRC_BSP_MIPI_H__

/* include */
#include <signal.h>
#include <unistd.h>
#include <sys/ioctl.h>          // IOCTL system call
#include <sys/prctl.h>
#include <sys/mman.h>
#include <time.h>

#include "bsp.h"
#include "global_variables.h"
#include "net_protocol.h"
#include "hal_rc8088.h"
#

/* define */
#define    ARM_DSP_SHARE_MEM_ADDR          (0xA7000000)


//初始化 dma data callback 信号量
#define  CMD_INIT_SINGNAL_INFO_CMD          100
//测试   SINGAL
#define  CMD_SEND_SIG_INFO_CMD              101
#define  CMD_SET_SI_SINGNO                  102
#define  CMD_SET_SI_ERRNO                   103
#define  CMD_SET_SI_CODE                    104
//测试  读数据read（）   设置读第几个 dma buf[index]  
#define  CMD_SEI_READ_DMA_BUF_INDEX         105

/* 初始化  MIPI硬件寄存器硬件设备 */
#define  CMD_INIT_TDA4_SHIM_DPHY_CSIRX      107  

/* 测试 打印dma buf的地址 数据 */
#define  CMD_TEST_PRINTK_ALLOC_INFO         108

/* 申请 释放 dma buf 的内存空间 */
#define  CMD_INIT_DMA_BUF_ALLOC             200
#define  CMD_RELEASE_DMA_BFU_ALLOC          201

/* 开始DMA  给入buf地址后，数据不放回后，不能再给入，会崩 */
#define  CMD_START_DMA_DATA_INIO_BUF        202

/* 给入下一个buf的index给dma */
#define  CMD_SET_DMA_BUF_INDEX              203

/* mmap buf的index给mmap */
#define  CMD_SET_MMAP_BUF_INDEX             204
//读寄存器的状态
#define  CMD_READ_DPHY_STATUS               205

/* 设置csi_rx_if start */
#define  CMD_START_CSI_RX_IF			    206
#define  CMD_STOP_CSI_RX_IF                 207
#define  CMD_SET_FRAME_DATA_LEN			    208
#define  CMD_SET_MIPI_FREQ				    209
#define  CMD_CLEAR_DMA_QUEUE			    210


#define   SIGN_SIGRTMIN                     34

/* typedef */
typedef struct 
{
    uint32_t mipi_num;                       // 最大mipi个数
    uint32_t mipi_thread_handle_num;         // mipi接收线程数量
    uint32_t mipi_input_fram_num;            // 需要采集的帧数
    uint32_t mipi_clk_freq;
    uint32_t mipi_fram_len;

    /* mipi 个数 */
    struct
    {
        int fd;                              // 设备节点
        uint8_t *dev_name;                   // 设备名称
        uint8_t *pu8_mmap;                   // 映射内存逻辑地址
        struct sigaction mipi_sigact;        // 底层系统信号
        uint32_t need_handle_fram_num;       // 需要处理的帧数
        uint32_t fram_count;                 // 帧数计数

        /* mipi接收信号及线程 */
        struct
        {
            sem_t     sem;                   // 线程信号量
            pthread_t thread_pid;            // 线程pid
        }info[MIPI_RECV_THREAD_NUM];

    }mipi_index[MIPI_CHANNEL_MAX];

}mipi_recv_info_type;


/* global varibles */
// 记录已经接收的mipi数据的帧数
extern uint32_t g_recv_mipi_frame_cnt;

// 记录已经接收的半帧mipi数据的次数
extern uint32_t g_recv_mipi_half_frame_cnt;

extern mipi_recv_info_type g_mipi_recv_info;
           

/* private function */

/* function */
uint32_t bsp_mipi_init(void);
uint32_t bsp_mipi_deinit(void);
uint32_t bsp_mipi_read(void);
uint32_t bsp_mipi_write(void);
uint32_t  bsp_mipi_start_dma(int index);

void *mipi_recv_thread(void *param);
void *dma_signal_callback_mipi0(int signum, siginfo_t *info, void *context);
void *dma_signal_callback_mipi1(int signum, siginfo_t *info, void *context);
void *dma_signal_callback_mipi2(int signum, siginfo_t *info, void *context);
void *dma_signal_callback_mipi3(int signum, siginfo_t *info, void *context);
void *mipi_capture_thread(void *param);
#endif